#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sqlite3.h>
#include "server.h"
#include "../common/common.h"
#include "../common/protocol.h"

Client clients[MAX_CLIENTS];
pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
sqlite3 *db;

void init_database() {
    int rc = sqlite3_open("chess_server.db", &db);
    if (rc) {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        exit(1);
    }
    
    // 创建用户表
    char *sql = "CREATE TABLE IF NOT EXISTS users (" \
                "id INTEGER PRIMARY KEY AUTOINCREMENT," \
                "username TEXT UNIQUE NOT NULL," \
                "password TEXT NOT NULL," \
                "elo_rating INTEGER DEFAULT 1200," \
                "is_online INTEGER DEFAULT 0);";
    
    rc = sqlite3_exec(db, sql, 0, 0, 0);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
    }
}

// 客户端管理函数
void add_client(int socket) {
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < MAX_CLIENTS; i++) {
        if (clients[i].socket == 0) {
            clients[i].socket = socket;
            clients[i].authenticated = false;
            memset(&clients[i].user, 0, sizeof(User));
            break;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
}

void remove_client(int socket) {
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < MAX_CLIENTS; i++) {
        if (clients[i].socket == socket) {
            clients[i].socket = 0;
            clients[i].authenticated = false;
            memset(&clients[i].user, 0, sizeof(User));
            break;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
}

int find_client_by_user_id(int user_id) {
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < MAX_CLIENTS; i++) {
        if (clients[i].authenticated && clients[i].user.id == user_id) {
            int socket = clients[i].socket;
            pthread_mutex_unlock(&clients_mutex);
            return socket;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
    return -1;
}

// 游戏房间管理
GameRoom game_rooms[50];
int room_count = 0;

void create_game_room(int player1_id, int player2_id) {
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < 50; i++) {
        if (game_rooms[i].room_id == 0) {
            game_rooms[i].room_id = i + 1;
            game_rooms[i].player1_id = player1_id;
            game_rooms[i].player2_id = player2_id;
            game_rooms[i].player1_side = 'W'; // 玩家1执白
            game_rooms[i].is_player1_turn = true;
            game_rooms[i].game_over = false;
            game_rooms[i].winner = ' ';
            
            // 初始化棋盘
            char initial_board[8][8] = {
                {'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'},
                {'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p'},
                {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
                {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
                {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
                {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
                {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'},
                {'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R'}
            };
            memcpy(game_rooms[i].board, initial_board, sizeof(initial_board));
            
            room_count++;
            break;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
}

void remove_game_room(int room_id) {
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < 50; i++) {
        if (game_rooms[i].room_id == room_id) {
            game_rooms[i].room_id = 0;
            room_count--;
            break;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
}

int find_game_room_by_player(int player_id) {
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < 50; i++) {
        if (game_rooms[i].room_id != 0 && 
            (game_rooms[i].player1_id == player_id || game_rooms[i].player2_id == player_id)) {
            int room_id = game_rooms[i].room_id;
            pthread_mutex_unlock(&clients_mutex);
            return room_id;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
    return -1;
}

int find_opponent_in_room(int room_id, int player_id) {
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < 50; i++) {
        if (game_rooms[i].room_id == room_id) {
            int opponent_id = (game_rooms[i].player1_id == player_id) ? 
                             game_rooms[i].player2_id : game_rooms[i].player1_id;
            pthread_mutex_unlock(&clients_mutex);
            return opponent_id;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
    return -1;
}

// 消息处理函数
void handle_login(int client_socket, Message *msg, User *current_user) {
    char username[32], password[32];
    sscanf(msg->data, "%[^:]:%s", username, password);
    
    // 数据库查询
    char *sql = "SELECT * FROM users WHERE username = ? AND password = ?";
    sqlite3_stmt *stmt;
    
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Database error");
        send_message(client_socket, &response);
        return;
    }
    
    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);
    
    rc = sqlite3_step(stmt);
    if (rc == SQLITE_ROW) {
        // 登录成功
        current_user->id = sqlite3_column_int(stmt, 0);
        strcpy(current_user->username, (const char*)sqlite3_column_text(stmt, 1));
        current_user->elo_rating = sqlite3_column_int(stmt, 3);
        current_user->is_online = true;
        
        // 更新在线状态
        char update_sql[100];
        sprintf(update_sql, "UPDATE users SET is_online = 1 WHERE id = %d", current_user->id);
        sqlite3_exec(db, update_sql, 0, 0, 0);
        
        // 添加到客户端列表
        pthread_mutex_lock(&clients_mutex);
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (clients[i].socket == client_socket) {
                clients[i].authenticated = true;
                clients[i].user = *current_user;
                break;
            }
        }
        pthread_mutex_unlock(&clients_mutex);
        
        Message response;
        response.type = MSG_LOGIN;
        sprintf(response.data, "%d:%s:%d", current_user->id, current_user->username, current_user->elo_rating);
        send_message(client_socket, &response);
    } else {
        // 登录失败
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Invalid username or password");
        send_message(client_socket, &response);
    }
    
    sqlite3_finalize(stmt);
}

void handle_register(int client_socket, Message *msg) {
    char username[32], password[32];
    sscanf(msg->data, "%[^:]:%s", username, password);
    
    // 检查用户名是否已存在
    char *check_sql = "SELECT * FROM users WHERE username = ?";
    sqlite3_stmt *check_stmt;
    
    int rc = sqlite3_prepare_v2(db, check_sql, -1, &check_stmt, 0);
    if (rc != SQLITE_OK) {
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Database error");
        send_message(client_socket, &response);
        return;
    }
    
    sqlite3_bind_text(check_stmt, 1, username, -1, SQLITE_STATIC);
    
    rc = sqlite3_step(check_stmt);
    if (rc == SQLITE_ROW) {
        // 用户名已存在
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Username already exists");
        send_message(client_socket, &response);
        sqlite3_finalize(check_stmt);
        return;
    }
    sqlite3_finalize(check_stmt);
    
    // 插入新用户
    char *insert_sql = "INSERT INTO users (username, password, elo_rating, is_online) VALUES (?, ?, 1200, 1)";
    sqlite3_stmt *insert_stmt;
    
    rc = sqlite3_prepare_v2(db, insert_sql, -1, &insert_stmt, 0);
    if (rc != SQLITE_OK) {
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Database error");
        send_message(client_socket, &response);
        return;
    }
    
    sqlite3_bind_text(insert_stmt, 1, username, -1, SQLITE_STATIC);
    sqlite3_bind_text(insert_stmt, 2, password, -1, SQLITE_STATIC);
    
    rc = sqlite3_step(insert_stmt);
    if (rc == SQLITE_DONE) {
        Message response;
        response.type = MSG_REGISTER;
        strcpy(response.data, "Registration successful");
        send_message(client_socket, &response);
    } else {
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Registration failed");
        send_message(client_socket, &response);
    }
    
    sqlite3_finalize(insert_stmt);
}

void handle_logout(int client_socket, User *current_user) {
    if (current_user->id != 0) {
        // 更新在线状态
        char update_sql[100];
        sprintf(update_sql, "UPDATE users SET is_online = 0 WHERE id = %d", current_user->id);
        sqlite3_exec(db, update_sql, 0, 0, 0);
        
        // 从客户端列表移除
        pthread_mutex_lock(&clients_mutex);
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (clients[i].socket == client_socket) {
                clients[i].authenticated = false;
                memset(&clients[i].user, 0, sizeof(User));
                break;
            }
        }
        pthread_mutex_unlock(&clients_mutex);
        
        memset(current_user, 0, sizeof(User));
    }
}

void handle_get_online_users(int client_socket) {
    char *sql = "SELECT id, username, elo_rating FROM users WHERE is_online = 1";
    sqlite3_stmt *stmt;
    
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Database error");
        send_message(client_socket, &response);
        return;
    }
    
    char user_list[1024] = "";
    
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        int id = sqlite3_column_int(stmt, 0);
        const char *username = (const char*)sqlite3_column_text(stmt, 1);
        int elo = sqlite3_column_int(stmt, 2);
        
        char user_info[50];
        sprintf(user_info, "%d:%s:%d;", id, username, elo);
        strcat(user_list, user_info);
    }
    
    // 移除最后一个分号
    if (strlen(user_list) > 0) {
        user_list[strlen(user_list) - 1] = '\0';
    }
    
    Message response;
    response.type = MSG_GET_ONLINE_USERS;
    strcpy(response.data, user_list);
    send_message(client_socket, &response);
    
    sqlite3_finalize(stmt);
}

void handle_request_game(int client_socket, Message *msg) {
    int opponent_id = msg->to_user_id;
    int opponent_socket = find_client_by_user_id(opponent_id);
    
    if (opponent_socket == -1) {
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Player is not online");
        send_message(client_socket, &response);
        return;
    }
    
    // 转发游戏请求给对手
    msg->to_user_id = opponent_id;
    send_message(opponent_socket, msg);
}

void handle_respond_game(int client_socket, Message *msg) {
    // 首先获取发送者的用户ID
    int sender_id = -1;
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < MAX_CLIENTS; i++) {
        if (clients[i].socket == client_socket) {
            sender_id = clients[i].user.id;
            break;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
    
    if (sender_id == -1) {
        printf("DEBUG: Sender not found\n");
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Sender not authenticated");
        send_message(client_socket, &response);
        return;
    }
    
    int opponent_id = msg->to_user_id;
    int opponent_socket = find_client_by_user_id(opponent_id);
    
    printf("DEBUG: Handling response game. Sender ID: %d, Opponent ID: %d, Socket: %d\n", 
           sender_id, opponent_id, opponent_socket);
    printf("DEBUG: Response data: %s\n", msg->data);

    if (opponent_socket == -1) {
        printf("DEBUG: Opponent not found or offline\n");
        Message response;
        response.type = MSG_ERROR;
        strcpy(response.data, "Player is not online");
        send_message(client_socket, &response);
        return;
    }
    
    // 转发响应给对手
    msg->from_user_id = sender_id; // 确保from_user_id正确设置
    msg->to_user_id = opponent_id;
    printf("DEBUG: Forwarding response to socket %d\n", opponent_socket);
    if (send_message(opponent_socket, msg) == 0) {
        printf("DEBUG: Response forwarded successfully\n");
    } else {
        printf("DEBUG: Failed to forward response\n");
    }
    
    // 在handle_respond_game函数中，修改游戏开始消息的发送
if (strcmp(msg->data, "accept") == 0) {
    create_game_room(opponent_id, sender_id);
    
    // 发送游戏开始消息给双方
    Message start_msg;
    start_msg.type = MSG_GAME_START;
    
    // 告诉发起者他执黑
    start_msg.to_user_id = opponent_id;
    sprintf(start_msg.data, "B:%d", sender_id); // B表示黑方，后面是对手ID
    int initiator_socket = find_client_by_user_id(opponent_id);
    if (initiator_socket != -1) {
        send_message(initiator_socket, &start_msg);
    }
    
    // 告诉接受者他执白
    start_msg.to_user_id = sender_id;
    sprintf(start_msg.data, "W:%d", opponent_id); // W表示白方，后面是对手ID
    send_message(client_socket, &start_msg);
}
}

// 修改 server.c 中的 handle_move 函数
void handle_move(int client_socket, Message *msg) {
    // 查找游戏房间
    int room_id = find_game_room_by_player(msg->from_user_id);
    if (room_id == -1) {
        // 没有找到游戏房间
        Message error_msg;
        error_msg.type = MSG_ERROR;
        strcpy(error_msg.data, "No active game found");
        send_message(client_socket, &error_msg);
        return;
    }
    
    // 找到对手的socket
    int opponent_id = find_opponent_in_room(room_id, msg->from_user_id);
    int opponent_socket = find_client_by_user_id(opponent_id);
    
    if (opponent_socket == -1) {
        // 对手不在线
        Message error_msg;
        error_msg.type = MSG_ERROR;
        strcpy(error_msg.data, "Opponent is not online");
        send_message(client_socket, &error_msg);
        return;
    }
    
    // 转发移动信息给对手
    msg->to_user_id = opponent_id;
    send_message(opponent_socket, msg);
    
    // 更新游戏房间中的棋盘状态
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < 50; i++) {
        if (game_rooms[i].room_id == room_id) {
            // 解析移动数据
            int from_row, from_col, to_row, to_col;
            char promotion_piece;
            sscanf(msg->data, "%d:%d:%d:%d:%c", &from_row, &from_col, &to_row, &to_col, &promotion_piece);
            
            // 执行移动
            char piece = game_rooms[i].board[from_row][from_col];
            game_rooms[i].board[to_row][to_col] = piece;
            game_rooms[i].board[from_row][from_col] = ' ';
            
            // 处理升变
            if (promotion_piece != ' ') {
                game_rooms[i].board[to_row][to_col] = promotion_piece;
            }
            
            // 切换回合
            game_rooms[i].is_player1_turn = !game_rooms[i].is_player1_turn;
            break;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
}

// 修改 server.c 中的 handle_promotion 函数
void handle_promotion(int client_socket, Message *msg) {
    // 处理兵升变消息
    int room_id = find_game_room_by_player(msg->from_user_id);
    if (room_id == -1) return;
    
    int opponent_id = find_opponent_in_room(room_id, msg->from_user_id);
    int opponent_socket = find_client_by_user_id(opponent_id);
    
    // 只将升变消息转发给对手，而不是双方
    if (opponent_socket != -1) {
        Message opponent_msg = *msg;
        opponent_msg.to_user_id = opponent_id;
        send_message(opponent_socket, &opponent_msg);
    }
    
    // 更新游戏房间中的棋盘状态
    pthread_mutex_lock(&clients_mutex);
    for (int i = 0; i < 50; i++) {
        if (game_rooms[i].room_id == room_id) {
            // 解析升变数据
            int row, col;
            char promotion_piece;
            sscanf(msg->data, "%d:%d:%c", &row, &col, &promotion_piece);
            
            // 执行升变
            game_rooms[i].board[row][col] = promotion_piece;
            break;
        }
    }
    pthread_mutex_unlock(&clients_mutex);
}

void handle_game_over(int client_socket, Message *msg) {
    // 处理游戏结束消息，与handle_move类似
    int room_id = find_game_room_by_player(msg->from_user_id);
    if (room_id == -1) return;
    
    int opponent_id = find_opponent_in_room(room_id, msg->from_user_id);
    int opponent_socket = find_client_by_user_id(opponent_id);
    
    if (opponent_socket != -1) {
        msg->to_user_id = opponent_id;
        send_message(opponent_socket, msg);
    }
    
    // 移除游戏房间
    remove_game_room(room_id);
}

void handle_resign(int client_socket, Message *msg) {
    // 处理认输消息，与handle_game_over类似
    handle_game_over(client_socket, msg);
}

void handle_cancel_game(int client_socket, Message *msg) {
    // 处理取消游戏请求
    int opponent_socket = find_client_by_user_id(msg->to_user_id);
    
    if (opponent_socket != -1) {
        Message cancel_msg;
        cancel_msg.type = MSG_RESPOND_GAME;
        strcpy(cancel_msg.data, "cancel");
        cancel_msg.to_user_id = msg->to_user_id;
        send_message(opponent_socket, &cancel_msg);
    }
}

void *handle_client(void *arg) {
    int client_socket = *((int *)arg);
    free(arg);
    
    Message msg;
    User current_user = {0};
    
    // 添加客户端到列表
    add_client(client_socket);
    
    while (1) {
        if (receive_message(client_socket, &msg) <= 0) {
            break;
        }
        
        switch (msg.type) {
            case MSG_LOGIN:
                handle_login(client_socket, &msg, &current_user);
                break;
            case MSG_REGISTER:
                handle_register(client_socket, &msg);
                break;
            case MSG_LOGOUT:
                handle_logout(client_socket, &current_user);
                break;
            case MSG_GET_ONLINE_USERS:
                handle_get_online_users(client_socket);
                break;
            case MSG_REQUEST_GAME:
                handle_request_game(client_socket, &msg);
                break;
            case MSG_RESPOND_GAME:
                handle_respond_game(client_socket, &msg);
                break;
            case MSG_MOVE:
                handle_move(client_socket, &msg);
                break;
            case MSG_PROMOTION:
                handle_promotion(client_socket, &msg);
                break;
            case MSG_GAME_OVER:
                handle_game_over(client_socket, &msg);
                break;
            case MSG_RESIGN:
                handle_resign(client_socket, &msg);
                break;
            case MSG_CANCEL_GAME:
                handle_cancel_game(client_socket, &msg);
                break;
            default:
                break;
        }
    }
    
    // 客户端断开连接
    handle_logout(client_socket, &current_user);
    remove_client(client_socket);
    close(client_socket);
    return NULL;
}

int main() {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_size;
    
    init_database();
    
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        perror("Socket error");
        exit(1);
    }
    
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    
    if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("Bind error");
        exit(1);
    }
    
    if (listen(server_socket, 10) == 0) {
        printf("Listening...\n");
    } else {
        perror("Listen error");
        exit(1);
    }
    
    while (1) {
        addr_size = sizeof(client_addr);
        client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &addr_size);
        
        if (client_socket < 0) {
            perror("Accept error");
            continue;
        }
        
        pthread_t tid;
        int *client_sock = malloc(sizeof(int));
        *client_sock = client_socket;
        
        pthread_create(&tid, NULL, handle_client, (void*)client_sock);
        pthread_detach(tid);
    }
    
    close(server_socket);
    sqlite3_close(db);
    return 0;
}
